package com.wchat.network.message;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import android.content.Context;
import android.content.Intent;

import com.wchat.network.Actions;
import com.wchat.network.Configs;

public class MessageReceiver extends Thread {
	
	private Context context;
	
	private volatile boolean close = false;
	
	DatagramSocket datagramSocket = null;
	
	private InetAddress localhost;

	public MessageReceiver(Context context, InetAddress localhost) {
		super();
		setName("MessageReceiver");
		this.context = context;
		this.localhost = localhost;
	}

	@Override
	public void run() {
		byte[] bytes = new byte[Configs.UDP_PACKET_LENGTH];
		try {
			datagramSocket = new DatagramSocket(Configs.UDP_PORT);
			DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
			while (!close) {
				try {
					datagramSocket.receive(datagramPacket);
				} catch (IOException e) {
					e.printStackTrace();
					continue;
				}

				if (close)
					break;
				
				try {
					Message message = Message.parserMessage(datagramPacket);
					InetAddress address = datagramPacket.getAddress();
					if (address != null && address.equals(localhost))
						continue;
					message.setFrom(address);
					message.setReceiveTimestamp(System.currentTimeMillis());
					if (!(message instanceof WhoAmIMessage)) {
					Configs.i("udp_receiver", "receiver message from: " + datagramPacket.getAddress().toString() + ", message: "
							+ message);
					}
					Intent intent = new Intent(Actions.ACTION_RECEIVE_MESSAGE);
					intent.putExtra("message", message);
					context.sendBroadcast(intent);
				} catch (Exception e) {
					Configs.assertFail("parse message error", e);
				}
				
				Thread.yield();
			}
		} catch (SocketException e) {
			e.printStackTrace();
		} finally {
			if (datagramSocket != null)
				datagramSocket.close();
		}
	}

	
	public void close() {
		close = true;
		datagramSocket.close();
	}
}
